#include "client_lib.h"
#include "cl_priv.h"
#include "uc_client.h"
#include "linkage_client.h"
#include "lan_dev_probe_priv.h"

static char *log_type_model(u_int16_t log_type);
extern void cl_no_lock_waste_time_item_add(void *pdata, void *proc, void *finish);

#ifdef	WIN32
const char *log_file = "d:\\cl_log.txt";
//const char *log_file = "x:\\wangyuanchao\\cl_log_w.txt";
//const char *log_file = "\\10.134.0.71\\home\\wangyuanchao";
//const char *log_file = "z:\\liubenlong\\cl_log.txt";
#elif defined (ANDROID)
#include <android/log.h>  
const char *log_file = NULL;
// log标签
#define  TAG    "CLibLog"
// 定义debug信息
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, TAG, __VA_ARGS__)
// 定义info信息
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,TAG, __VA_ARGS__)
// 定义error信息
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,TAG, __VA_ARGS__)
#else
#ifdef LC
const char *log_file = "/tmp/cl_log.txt";
#else
const char *log_file = NULL;
#endif
#endif

#define	LOG_BUF_SIZE	(16*1024)

//network dianosis file max
#define ND_LOG_FILE_SIZE		(2*1024*1024)

//debug dir
#define ND_LOG_DIR			"log"

//#define LOG_TO_PHONE_FILE

static bool is_init_dest_file = false;
static char log_dest_file[256] = {0};

static bool net_log_proc(char *buf);

static void init_log_file()
{
#ifndef WIN32
    if(is_init_dest_file){
        return;
    }
    
    if(cl_priv != NULL && cl_priv->dir[0] != '\0'){
        sprintf(log_dest_file,"%s/cl_log.txt",cl_priv->dir);
        log_file = log_dest_file;
        is_init_dest_file = true;
    }
#endif
}

static bool log_to_file(char* buf,int len)
{
    FILE *fp;

#ifdef LOG_TO_PHONE_FILE
    init_log_file();
#endif
    
    if (log_file != NULL) {
        if ((fp = cl_fopen(log_file, "a+")) != NULL) {
            fwrite(buf, len, 1, fp);
            fclose(fp);
            
            return true;
        }
    }
    return false;
}

void _log_debug(u_int16_t log_type, const char *fmt, ...)
{
	int pos = 0;
	char *buf;
	va_list vl;
	u_int32_t now;
	time_t now_s = time(NULL);
	char *model = log_type_model(log_type);
	char *cstr = NULL;

	if (!model) {
		return;
	}

	now = get_msec();
	buf = malloc(LOG_BUF_SIZE+64);

	//去掉换行
	cstr = ctime(&now_s);
	cstr[strlen(cstr) - 1] = 0;
    va_start(vl, fmt);
	pos += sprintf(buf + pos, "%s [%s][DEBUG] %u:%03u: ", cstr, model, now/1000, now%1000);
	pos += vsnprintf(buf + pos, LOG_BUF_SIZE-pos, fmt, vl);
    va_end(vl);

	//优先网络打印
	if (net_log_proc(buf)) {
		free(buf);
		return;
	}
	
    if (log_to_file(buf,pos)) {
        free(buf);
        return;
    }
    
#ifdef ANDROID
    LOGD("%s", buf);
#else
    printf("%s",buf);
#endif
    
	free(buf);
}

void _xlog_debug(const char *fmt, ...)
{
	int pos = 0;
	char *buf;
	va_list vl;
	u_int32_t now;
	time_t now_s = time(NULL);
	char *cstr = NULL;

	now = get_msec();
	buf = malloc(LOG_BUF_SIZE+64);

	//去掉换行
	cstr = ctime(&now_s);
	cstr[strlen(cstr) - 1] = 0;
    va_start(vl, fmt);
	pos += sprintf(buf + pos, "%s[DEBUG] %u:%03u: ", cstr, now/1000, now%1000);
	pos += vsnprintf(buf + pos, LOG_BUF_SIZE-pos, fmt, vl);
    va_end(vl);

	//优先网络打印
	if (net_log_proc(buf)) {
		free(buf);
		return;
	}
	
    if (log_to_file(buf,pos)) {
        free(buf);
        return;
    }
    
#ifdef ANDROID
    LOGD("%s", buf);
#else
    printf("%s",buf);
#endif
    
	free(buf);
}


void _log_info(u_int16_t log_type, const char *file, int line, const char *fmt, ...)
{
	int pos = 0;
	char *buf;
    va_list vl;
	u_int32_t now;
	time_t now_s = time(NULL);
	char *model = log_type_model(log_type);
	char *cstr = NULL;
	
	if (!model) {
		return;
	}

	now = get_msec();
	buf = malloc(LOG_BUF_SIZE+64);

	//去掉换行
	cstr = ctime(&now_s);
	cstr[strlen(cstr) - 1] = 0;
    va_start(vl, fmt);
	pos += sprintf(buf + pos, "%s [%s][INFO]  %u:%03u: %s line %u: ", cstr, model, now/1000, now%1000, file, line);
	pos += vsnprintf(buf + pos, LOG_BUF_SIZE-pos, fmt, vl);
    va_end(vl);

	//优先网络打印
	if (net_log_proc(buf)) {
		free(buf);
		return;
	}
	
    if (log_to_file(buf,pos)) {
        free(buf);
        return;
    }
    
#ifdef ANDROID
    LOGI("%s", buf);
#else
    printf("%s",buf);
#endif

	free(buf);
}

void _log_err(u_int16_t log_type, const char *file, int line, bool print_err, const char *fmt, ...)
{
	int pos = 0;
	char *buf;
	int ecode;
    va_list vl;
	u_int32_t now;
	time_t now_s = time(NULL);
	char *model = log_type_model(log_type);
	char *cstr = NULL;

	if (!model) {
		return;
	}	
	ecode = GET_SOCK_ECODE();

	now = get_msec();
	buf = malloc(LOG_BUF_SIZE+64);
	//去掉换行
	cstr = ctime(&now_s);
	cstr[strlen(cstr) - 1] = 0;
    va_start(vl, fmt);
	pos += sprintf(buf + pos, "%s [%s][ERROR] %u:%03u: %s line %d: ", cstr, model, now/1000, now%1000, file, line);
	pos += vsnprintf(buf + pos, LOG_BUF_SIZE-pos, fmt, vl);
    va_end(vl);
	if (print_err && ecode != 0) {
#ifdef WIN32			
		char *lpMsgBuf;

		FormatMessage(
			FORMAT_MESSAGE_ALLOCATE_BUFFER |
			FORMAT_MESSAGE_FROM_SYSTEM |
			FORMAT_MESSAGE_IGNORE_INSERTS,
			NULL,
			ecode,
			0,
			(LPTSTR) &lpMsgBuf,
			0,
			NULL
			);

		if (lpMsgBuf != NULL) {
			pos += sprintf(buf + pos, "        [ERROR] %s\n", lpMsgBuf);
			LocalFree(lpMsgBuf);
		}
#else
		pos += sprintf(buf + pos, "        [ERROR] %s\n", strerror(ecode));
#endif
	} else {
		pos += sprintf(buf + pos, "\n");
	}

	//优先网络打印
	if (net_log_proc(buf)) {
		free(buf);
		return;
	}
	
    if (log_to_file(buf,pos)) {
        free(buf);
        return;
    }
    
#ifdef ANDROID
    LOGE("%s", buf);
#else
    printf("%s",buf);
#endif

	free(buf);	
}

void _cl_assert(bool b, const char *file, int line)
{
	if ( ! b ) {
		log_err(false, "%s line %d assert failed!!!\n", file, line);
		*(char *)0 = 0;
	}
}

#define MAX_MEM_DUMP_LEN	(1024*10)
void memdumpone(char* pre,void* dest, u_int32_t len)
{
    u_int8_t* p = dest;
    u_int32_t i;
	int index = 0;
	int line = 0;
	char buff[MAX_MEM_DUMP_LEN];
	u_int16_t *pdata = (u_int16_t *)dest;
    
    if (!p) {
        return;
    }
    
    if (pre) {
        index += sprintf(buff+index, "%s:\n",pre);
    }

	index += sprintf(buff + index, "%-5d  ", line++);
    for (i = 0; i<len; i++) {
        if (i>0 && i%16 == 0) {
           index += snprintf(buff + index, MAX_MEM_DUMP_LEN - index, "\n");
		   index += snprintf(buff + index, MAX_MEM_DUMP_LEN - index, "%d  ", line++);
        }
        
        index += snprintf(buff+index, MAX_MEM_DUMP_LEN - index, "%02x ",p[i]);
    }
    
    _log_debug(LOG_TYPE_MEMDUMP, "%s\n", buff);
    
}

void memdump(char* pre,void* dest, u_int32_t len)
{
    u_int8_t* p = dest;
    u_int32_t i;
	int index = 0;
	int line = 0;
	char buff[MAX_MEM_DUMP_LEN];
	u_int16_t *pdata = (u_int16_t *)dest;

	if (len > 512) {
		len = 512;
	}
    
    if (!p) {
        return;
    }
    
    if (pre) {
        index += sprintf(buff+index, "%s:\n",pre);
    }

	index += sprintf(buff + index, "%-5d  ", line++);
    for (i = 0; i<len; i++) {
        if (i>0 && i%16 == 0) {
           index += snprintf(buff + index, MAX_MEM_DUMP_LEN - index, "\n");
		   index += snprintf(buff + index, MAX_MEM_DUMP_LEN - index, "%-5d  ", line++);
        }
        
        index += snprintf(buff+index, MAX_MEM_DUMP_LEN - index, "%02x ",p[i]);
    }
    
    _log_debug(LOG_TYPE_MEMDUMP, "%s\n", buff);
}

static void nd_file_clean(char *file)
{
	FILE *fp = NULL;

	fp = fopen(file, "w");

	if (fp) {
		fclose(fp);
	}
}

static FILE *nd_init_output(char *file_prefix)
{
	struct stat stat1,stat2;
	int exist1 = 0,exist2 = 0, fnum = 0;
	char buf[300];
	char file1[300];
	char file2[300];
	char log_dir[300];
	FILE *fp = NULL;
	u_int32_t debug_size_limit = ND_LOG_FILE_SIZE;

	if (!cl_priv->dir) {
		return NULL;
	}
	if (debug_size_limit < cl_priv->nd_debug_size) {
		debug_size_limit = cl_priv->nd_debug_size;
	}

	//dir create
	sprintf(log_dir, "%s/%s", cl_priv->dir, ND_LOG_DIR);
	MKDIR(log_dir, 0777);
	
	sprintf(file1, "%s/%s/%s%d.txt", cl_priv->dir, ND_LOG_DIR, file_prefix, 0);
	sprintf(file2, "%s/%s/%s%d.txt", cl_priv->dir, ND_LOG_DIR, file_prefix, 1);
	exist1 = cl_access(file1,0)?0:1;
	exist2 = cl_access(file2,0)?0:1;
	if(exist1){
		if(stat(file1,&stat1)!=0){
			nd_file_clean(file1);
			exist1 =0;
		}
	}
	if(exist2){
		if(stat(file2,&stat2)){
			nd_file_clean(file2);
			exist2 =0;
		}
	}

	if(!exist1 && !exist2) {
		goto end;
	}
	if(exist1){
		if(exist2){
			if((u_int32_t)stat1.st_size < debug_size_limit) {
				goto end;
			}
			if((u_int32_t)stat2.st_size < debug_size_limit){
				fnum = 1;
				goto end;
			}

			if((u_int32_t)stat2.st_mtime <= stat1.st_mtime){
				fnum = 1;
				nd_file_clean(file2);
				goto end;
			}else{
				nd_file_clean(file1);
				goto end;
			}

		}

		if((u_int32_t)stat1.st_size >= debug_size_limit) {
			fnum = 1;
		}
		goto end;
	}

	if((u_int32_t)stat2.st_size >= debug_size_limit) {
		fnum =0;
	} else {
		fnum = 1;
	}

end:
	sprintf(buf,"%s/%s/%s%d.txt",cl_priv->dir , ND_LOG_DIR, file_prefix ,fnum&0x1);
	fp = fopen(buf, "a");

	return fp;
}

static void _nd_log_to_file(char* buf,int len, char *file_prefix)
{
    FILE *fp;

	fp = nd_init_output(file_prefix);
    if (!fp) {
		return;
	}

    fwrite(buf, len, 1, fp);
    fclose(fp);
}

#define ND_BUFF_SIZE	(1024)
void _nd_login_debug(void *in_s, const char *fmt, ...)
{
	int pos = 0;
	char buf[ND_BUFF_SIZE];
	va_list vl;
	u_int32_t now_msec;
	time_t now_s;
	char time_str[100] = {0};
	ucc_session_t *s = (ucc_session_t *)in_s;

	// TODO:这里判断下是否开启打印
	if (!cl_priv->nd_debug) {
		return;
	}
	now_msec = get_msec();
	now_s = time(NULL);

	sprintf(time_str, "%s", ctime(&now_s));
	time_str[strlen(time_str)-1] = 0;
	
    va_start(vl, fmt);
	pos += sprintf(buf + pos, "[sn=%"PRIu64"]time=%s %u:%03u: \r\n", 
		s?s->user->sn:0, time_str, now_msec/1000, now_msec%1000);
	pos += vsnprintf(buf + pos, ND_BUFF_SIZE-pos, fmt, vl);
    va_end(vl);
    
    _nd_log_to_file(buf,pos, "login_debug");
}

void _nd_misc_debug(void *in_s, const char *fmt, ...)
{
	int pos = 0;
	char buf[ND_BUFF_SIZE];
	va_list vl;
	u_int32_t now_msec;
	time_t now_s;
	char time_str[100] = {0};
	ucc_session_t *s = (ucc_session_t *)in_s;

	// TODO:这里判断下是否开启打印
	if (!cl_priv->nd_debug) {
		return;
	}
	now_msec = get_msec();
	now_s = time(NULL);

	sprintf(time_str, "%s", ctime(&now_s));
	time_str[strlen(time_str)-1] = 0;
	
    va_start(vl, fmt);
	pos += sprintf(buf + pos, "[sn=%"PRIu64"] time=%s %u:%03u: \r\n", 
		s?s->user->sn:0, time_str, now_msec/1000, now_msec%1000);
	pos += vsnprintf(buf + pos, ND_BUFF_SIZE-pos, fmt, vl);
    va_end(vl);
    
    _nd_log_to_file(buf,pos, "misc_debug");
}


void _nd_misc_info(const char *file, int line, void *in_s, const char *fmt, ...)
{
	int pos = 0;
	char buf[ND_BUFF_SIZE];
	va_list vl;
	u_int32_t now_msec;
	time_t now_s;
	char time_str[100] = {0};
	ucc_session_t *s = (ucc_session_t *)in_s;

	// TODO:这里判断下是否开启打印
	if (!cl_priv->nd_debug) {
		return;
	}
	now_msec = get_msec();
	now_s = time(NULL);

	sprintf(time_str, "%s", ctime(&now_s));
	time_str[strlen(time_str)-1] = 0;
	
    va_start(vl, fmt);
	pos += sprintf(buf + pos, "[sn=%"PRIu64"]time=%s %u:%03u: %s line=%u:\r\n", 
		s?s->user->sn:0, time_str, now_msec/1000, now_msec%1000, 
		file, line);
	pos += vsnprintf(buf + pos, ND_BUFF_SIZE-pos, fmt, vl);
    va_end(vl);
    
    _nd_log_to_file(buf,pos, "misc_debug");
}


void _nd_login_info(const char *file, int line, void *in_s, const char *fmt, ...)
{
	int pos = 0;
	char buf[ND_BUFF_SIZE];
	va_list vl;
	u_int32_t now_msec;
	time_t now_s;
	char time_str[100] = {0};
	ucc_session_t *s = (ucc_session_t *)in_s;

	// TODO:这里判断下是否开启打印
	if (!cl_priv->nd_debug) {
		return;
	}
	now_msec = get_msec();
	now_s = time(NULL);

	sprintf(time_str, "%s", ctime(&now_s));
	time_str[strlen(time_str)-1] = 0;
	
    va_start(vl, fmt);
	pos += sprintf(buf + pos, "[sn=%"PRIu64"]time=%s %u:%03u: %s line=%u:\r\n", 
		s?s->user->sn:0, time_str, now_msec/1000, now_msec%1000, 
		file, line);
	pos += vsnprintf(buf + pos, ND_BUFF_SIZE-pos, fmt, vl);
    va_end(vl);
    
    _nd_log_to_file(buf,pos, "login_debug");
}

void _nd_la_debug(void *in_s, const char *fmt, ...)
{
	int pos = 0;
	char buf[ND_BUFF_SIZE];
	va_list vl;
	u_int32_t now_msec;
	time_t now_s;
	char time_str[100] = {0};
	ucla_session_t *s = (ucla_session_t *)in_s;

	// TODO:这里判断下是否开启打印
	if (!cl_priv->nd_debug) {
		return;
	}
	now_msec = get_msec();
	now_s = time(NULL);

	sprintf(time_str, "%s", ctime(&now_s));
	time_str[strlen(time_str)-1] = 0;
	
    va_start(vl, fmt);
	pos += sprintf(buf + pos, "[doname=%s] time=%s %u:%03u: \r\n", 
		s?s->doname:"null", time_str, now_msec/1000, now_msec%1000);
	pos += vsnprintf(buf + pos, ND_BUFF_SIZE-pos, fmt, vl);
    va_end(vl);
    
    _nd_log_to_file(buf,pos, "la_debug");
}

void _nd_la_info(const char *file, int line, void *in_s, const char *fmt, ...)
{
	int pos = 0;
	char buf[ND_BUFF_SIZE];
	va_list vl;
	u_int32_t now_msec;
	time_t now_s;
	char time_str[100] = {0};
	ucla_session_t *s = (ucla_session_t *)in_s;

	// TODO:这里判断下是否开启打印
	if (!cl_priv->nd_debug) {
		return;
	}
	now_msec = get_msec();
	now_s = time(NULL);

	sprintf(time_str, "%s", ctime(&now_s));
	time_str[strlen(time_str)-1] = 0;
	
    va_start(vl, fmt);
	pos += sprintf(buf + pos, "[doname=%s] time=%s %u:%03u: %s line=%u:\r\n", 
		s?s->doname:"null", time_str, now_msec/1000, now_msec%1000, file, line);
	pos += vsnprintf(buf + pos, ND_BUFF_SIZE-pos, fmt, vl);
    va_end(vl);
    
    _nd_log_to_file(buf,pos, "la_debug");
}

void _nd_lan_debug(void *in_dev, const char *fmt, ...)
{
	int pos = 0;
	char buf[ND_BUFF_SIZE];
	va_list vl;
	u_int32_t now_msec;
	time_t now_s;
	char time_str[100] = {0};
	dev_probe_info_t* dev = (dev_probe_info_t *)in_dev;

	// TODO:这里判断下是否开启打印
	if (!cl_priv->nd_debug) {
		return;
	}
	now_msec = get_msec();
	now_s = time(NULL);

	sprintf(time_str, "%s", ctime(&now_s));
	time_str[strlen(time_str)-1] = 0;
	
    va_start(vl, fmt);
	pos += sprintf(buf + pos, "[lan sn=%"PRIu64"] time=%s %u:%03u: \r\n", 
		dev?dev->dev_sn:0, time_str, now_msec/1000, now_msec%1000);
	pos += vsnprintf(buf + pos, ND_BUFF_SIZE-pos, fmt, vl);
    va_end(vl);
    
    _nd_log_to_file(buf,pos, "lan_debug");
}

void _nd_lan_info(const char *file, int line, void *in_dev, const char *fmt, ...)
{
	int pos = 0;
	char buf[ND_BUFF_SIZE];
	va_list vl;
	u_int32_t now_msec;
	time_t now_s;
	dev_probe_info_t* dev = (dev_probe_info_t *)in_dev;
	char time_str[100] = {0};

	// TODO:这里判断下是否开启打印
	if (!cl_priv->nd_debug) {
		return;
	}
	now_msec = get_msec();
	now_s = time(NULL);

	sprintf(time_str, "%s", ctime(&now_s));
	time_str[strlen(time_str)-1] = 0;
	
    va_start(vl, fmt);
	pos += sprintf(buf + pos, "[lan sn=%"PRIu64"] time=%s %u:%03u: %s line=%u: \r\n", 
		dev?dev->dev_sn:0, time_str, now_msec/1000, now_msec%1000, file, line);
	pos += vsnprintf(buf + pos, ND_BUFF_SIZE-pos, fmt, vl);
    va_end(vl);
    
    _nd_log_to_file(buf,pos, "lan_debug");
}

void nd_login_memdump(char* pre,void* dest, u_int32_t len)
{
    u_int8_t* p = dest;
    u_int32_t i;
	int index = 0;
	int line = 0;
	char buff[ND_BUFF_SIZE];
	u_int16_t *pdata = (u_int16_t *)dest;

	if (!cl_priv->nd_debug) {
		return;
	}
	if (len > ND_BUFF_SIZE) {
		len = ND_BUFF_SIZE;
	}
    if (!p) {
        return;
    }
    if (pre) {
        index += sprintf(buff+index, "%s:\n",pre);
    }
	index += sprintf(buff + index, "%-5d  ", line++);
    for (i = 0; i<len; i++) {
        if (i>0 && i%16 == 0) {
           index += snprintf(buff + index, ND_BUFF_SIZE - index, "\n");
		   index += snprintf(buff + index, ND_BUFF_SIZE - index, "%d  ", line++);
        }
        
        index += snprintf(buff+index, ND_BUFF_SIZE - index, "%02x ",p[i]);
    }
	_nd_log_to_file(buff,index, "login_debug");
}

void nd_la_memdump(char* pre,void* dest, u_int32_t len)
{
    u_int8_t* p = dest;
    u_int32_t i;
	int index = 0;
	int line = 0;
	char buff[ND_BUFF_SIZE];
	u_int16_t *pdata = (u_int16_t *)dest;

	if (!cl_priv->nd_debug) {
		return;
	}
	if (len > ND_BUFF_SIZE) {
		len = ND_BUFF_SIZE;
	}
    if (!p) {
        return;
    }
    if (pre) {
        index += sprintf(buff+index, "%s:\n",pre);
    }
	index += sprintf(buff + index, "%-5d  ", line++);
    for (i = 0; i<len; i++) {
        if (i>0 && i%16 == 0) {
           index += snprintf(buff + index, ND_BUFF_SIZE - index, "\n");
		   index += snprintf(buff + index, ND_BUFF_SIZE - index, "%d  ", line++);
        }
        
        index += snprintf(buff+index, ND_BUFF_SIZE - index, "%02x ",p[i]);
    }

	index += snprintf(buff+index, ND_BUFF_SIZE - index, "\n");
	_nd_log_to_file(buff,index, "la_debug");
}


void nd_lan_memdump(char* pre,void* dest, u_int32_t len)
{
    u_int8_t* p = dest;
    u_int32_t i;
	int index = 0;
	int line = 0;
	char buff[ND_BUFF_SIZE];
	u_int16_t *pdata = (u_int16_t *)dest;

	if (!cl_priv->nd_debug) {
		return;
	}
	if (len > ND_BUFF_SIZE) {
		len = ND_BUFF_SIZE;
	}
    if (!p) {
        return;
    }
    if (pre) {
        index += sprintf(buff+index, "%s:\n",pre);
    }
	index += sprintf(buff + index, "%-5d  ", line++);
    for (i = 0; i<len; i++) {
        if (i>0 && i%16 == 0) {
           index += snprintf(buff + index, ND_BUFF_SIZE - index, "\n");
		   index += snprintf(buff + index, ND_BUFF_SIZE - index, "%d  ", line++);
        }
        
        index += snprintf(buff+index, ND_BUFF_SIZE - index, "%02x ",p[i]);
    }
	_nd_log_to_file(buff,index, "lan_debug");
}

#define STR(R) #R
static log_type_t log_amdin[LOG_TYPE_MAX] = {
	{STR(LOG_TYPE_IDLE), false, 10},
	{STR(LOG_TYPE_MEMDUMP), false, 3},
	{STR(LOG_TYPE_LINKAGE_CLIENT), false, 1},
	{STR(LOG_TYPE_LINKAGE_PRIV), false, 1},
	{STR(LOG_TYPE_UC_CLIENT), false, 2},
	{STR(LOG_TYPE_UAS_CLIENT), false, 2},
	{STR(LOG_TYPE_UASC_PRIV), false, 2},
	{STR(LOG_TYPE_TCP_MISC_PROC), false, 3},
	{STR(LOG_TYPE_RFGW_PRIV), false, 4},
	{STR(LOG_TYPE_UDP_RF_DEV), false, 4},
	{STR(LOG_TYPE_CL_USER), false, 3},
	{STR(LOG_TYPE_APP_DATA_SYNC), false, 5},
	{STR(LOG_TYPE_CLIENT_LIB), false, 5},
	{STR(LOG_TYPE_CL_DNS), false, 5},
	{STR(LOG_TYPE_CL_MAIN), false, 6},
	{STR(LOG_TYPE_CL_NOTIFY), false, 6},
	{STR(LOG_TYPE_CMD_MISC), false, 6},
	{STR(LOG_TYPE_DNS_CLIENT), false, 6},
	{STR(LOG_TYPE_MISC_CLIENT), false, 6},
	{STR(LOG_TYPE_UC_AGENT), false, 3},
	{STR(LOG_TYPE_UDP_DEVICE_COMMON_PRIV), false, 4},
	{STR(LOG_TYPE_VIDEO_PRIV), false, 10},
	{STR(LOG_TYPE_YINSU_SCM_CTRL), false, 10},
	{STR(LOG_TYPE_USER_PRIV), false, 3},
	{STR(LOG_TYPE_CL_THREAD), false, 0xff},
	{STR(LOG_TYPE_SPECIAL), true, 0xfe},	
};
static char *log_type_model(u_int16_t log_type)
{
	if ((log_type < LOG_TYPE_MAX) && log_amdin[log_type].valid) {
		return log_amdin[log_type].model;
	}

	return NULL;
}


RS _log_output_path(const char *path)
{
	log_file = path;
	
	return RS_OK;
}

RS _log_output_model(u_int16_t model, bool output)
{
	int i;
	if (model < LOG_TYPE_MAX) {
		log_amdin[model].valid = output;
	} else if (model == 0xffff) {
		for (i = 0; i < LOG_TYPE_MAX; i++) {
			log_amdin[i].valid = output;
		}
	}
	
	return RS_OK;
}

RS _log_set_level(int level)
{
	int i;

	for (i = 0; i < LOG_TYPE_MAX; i++) {
		if (log_amdin[i].level <= level) {
			log_amdin[i].valid = true;
		} else {
			log_amdin[i].valid = false;
		}
	}

	return RS_OK;
}

RS _log_model_get(int *num, log_type_t *model)
{
	memcpy((void *)model, (void *)log_amdin, sizeof(log_amdin));
	*num = LOG_TYPE_MAX;

	return RS_OK;
}

#include "hiredis.h"
char redis_addr[200] = {0};
char redis_app[200] = {0};
u_int16_t redis_port = 0;
char redis_desc[200] = {0};
RS _net_log_redis_conf_init(char *addr, u_int16_t port, char *app, char *desc)
{
	net_log_admin_t *ad = &cl_priv->nadmin;
	redisContext *pc = NULL;
	RS ret = RS_OK;

	strncpy(redis_addr, addr, sizeof(redis_addr) -1);
	strncpy(redis_desc, desc, sizeof(redis_desc) -1);
	strncpy(redis_app, app, sizeof(redis_app) -1);
	redis_port = port;
	
	cl_lock(&ad->mutex);
	
	//先释放上次的
	if (ad->redis) {
		redisFree(ad->redis);
		ad->redis = NULL;
	}
	if (redis_port != 0) {
		pc = redisConnect(redis_addr, redis_port);	
		if (pc && pc->err == 0) {
			ad->redis = pc;
		} else {
			ret = RS_ERROR;
		}
	}
	
	cl_unlock(&ad->mutex);

	return ret;
}

void cl_net_log_init(void)
{
}

void cl_net_log_stop(void)
{
	net_log_admin_t *ad = NULL;

	if (!cl_priv) {
		return;
	}
	
	ad = &cl_priv->nadmin;

	if (!ad->redis) {
		return;
	}
	cl_lock(&ad->mutex);
	redisFree(ad->redis);
	ad->redis = NULL;
	cl_unlock(&ad->mutex);	
}

static bool net_log_proc(char *buf)
{
	net_log_admin_t *ad = &cl_priv->nadmin;
	void *reply = NULL;
	
	if (!ad->redis) {
		return false;
	}
	cl_lock(&ad->mutex);
	reply = redisCommand(ad->redis, "LPUSH %s %s=%s", redis_app, redis_desc, buf);
	cl_unlock(&ad->mutex);	
	if (reply) {
		freeReplyObject(reply);
	}
	
	return true;
}


